package net.skycloud.f5.controller;


import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.annotations.*;
import net.skycloud.f5.exception.ObjectNotFoundException;
import net.skycloud.f5.model.DeviceCredential;
import net.skycloud.f5.service.DeviceCredentialService;
import net.skycloud.f5.util.PageInfo;
import net.skycloud.f5.validation.ADD;
import net.skycloud.f5.validation.UPDATE;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

import javax.servlet.http.HttpServletResponse;
import java.net.URI;
import java.util.*;

/**
 * @Author xiongmin
 * @Description //TODO
 * @Date 2019/12/18 17:19
 * @Version 1.0
 **/
@RestController
@RequestMapping(value = "/device-credentials")
@CrossOrigin(value = "*")
@Api(value = "Device Credential", description = "设备连接凭证API")
public class DeviceCredentialController {

    private static final Logger logger = LoggerFactory.getLogger(DeviceCredentialController.class);

    @Autowired
    private DeviceCredentialService credentialService;

    @RequestMapping(value = "", method = RequestMethod.POST)
    @ApiOperation(
            value = "添加新的凭证",
            notes = "可调用角色[ROLE_ADMIN]",
            code = 201,
            consumes = "application/json",
            produces = "application/json"
    )
    @ApiResponses(value = {
            @ApiResponse(code = 201, message = "创建成功", responseHeaders = {
                    @ResponseHeader(name = "location", response = String.class, description = "创建资源链接")
            }),
            @ApiResponse(code = 409, message = "名称冲突")
    })
    public void create(
            @ApiParam(value = "连接凭证,必填字段name,type,value,选填字段description")
            @Validated({ADD.class})
            @RequestBody DeviceCredential deviceCredential,
            HttpServletResponse response) throws Exception {

        logger.debug("Adding device credential {}.", deviceCredential);

        if (deviceCredential.getId() == null) {
            deviceCredential.setId(UUID.randomUUID());
        }
        deviceCredential.setName(deviceCredential.getName().trim());
        deviceCredential.setCreatedAt(new Date());
        deviceCredential.setUpdatedAt(new Date());

        DeviceCredential res = credentialService.add(deviceCredential);
        URI location = ServletUriComponentsBuilder.fromCurrentRequestUri().path("/{id}")
                .buildAndExpand(res.getId()).toUri();
        response.setStatus(HttpStatus.CREATED.value());
        response.setHeader("location", location.toString());
    }

    @RequestMapping(value = "/{id}", method = RequestMethod.PUT)
    @ApiOperation(
            value = "更新指定的凭证",
            notes = "可调用角色[ROLE_ADMIN]",
            code = 200,
            consumes = "application/json",
            produces = "application/json"
    )
    @ApiResponses(value = {
            @ApiResponse(code = 404, message = "无更新对象")
    })
    public DeviceCredential update(
            @ApiParam(value = "凭证UUID") @PathVariable UUID id,
            @ApiParam(value = "更新的字段,允许更新name,type,value,description")
            @Validated({UPDATE.class})
            @RequestBody DeviceCredential credential) throws Exception {

        logger.debug("Updating device credential {}.", id);

        DeviceCredential credentialById = credentialService.getCredentialById(id);
        credential.setData(credentialById.getData());


        credential.setId(id);
        return credentialService.update(credential);
    }

    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
    @ApiOperation(
            value = "删除指定的凭证",
            notes = "可调用角色[ROLE_ADMIN]",
            code = 200,
            consumes = "application/json",
            produces = "application/json"
    )
    @ApiResponses(value = {
            @ApiResponse(code = 404, message = "无更新对象")
    })
    public void delete(
            @ApiParam(value = "凭证UUID") @PathVariable UUID id) throws Exception {

        logger.debug("Deleting device credential {}.", id);
        credentialService.deleteById(id);
    }

    @RequestMapping(value = "", method = RequestMethod.GET)
    @ApiOperation(
            value = "获取凭证列表",
            notes = "可调用角色[ROLE_ADMIN, ROLE_USER]",
            code = 200,
            consumes = "application/json",
            produces = "application/json"
    )
    public PageInfo<DeviceCredential> getAll(
            @ApiParam(value = "页码，从0开始，默认为0") @RequestParam(name = "page", required = false, defaultValue = "0") Integer page,
            @ApiParam(value = "每页大小，默认20") @RequestParam(name = "size", required = false, defaultValue = "20") Integer size
    ) throws Exception {
        logger.debug("Getting device credential list.");
        PageInfo<DeviceCredential> credentialServiceAll = credentialService.getAll(page, size);
        List<DeviceCredential> list = credentialServiceAll.getList();
        ObjectMapper objectMapper = new ObjectMapper();
        for (DeviceCredential res : list) {
            String value = res.getData();
            Map<String, String> map = new HashMap<String, String>();
            JSONObject jsonObject = new JSONObject(value);
            map.put("username", jsonObject.get("username").toString());
            map.put("password", "******");
            res.setData(objectMapper.writeValueAsString(map));
        }

        return credentialServiceAll;
    }

    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    @ApiOperation(
            value = "获取指定的凭证信息",
            notes = "可调用角色[ROLE_ADMIN, ROLE_USER]",
            code = 200,
            consumes = "application/json",
            produces = "application/json"
    )
    @ApiResponses(value = {
            @ApiResponse(code = 404, message = "无查询对象")
    })
    public DeviceCredential getCredentialById(
            @ApiParam(value = "凭证UUID")
            @PathVariable UUID id) throws Exception {

        logger.debug("Getting device credential by id [{}].", id);
        DeviceCredential res = credentialService.getCredentialById(id);
        if (res == null) {
            throw new ObjectNotFoundException("No such device credential.");
        }

        ObjectMapper objectMapper = new ObjectMapper();
        String value = res.getData();
        Map<String, String> map = new HashMap<String, String>();
        JSONObject jsonObject = new JSONObject(value);
        map.put("username", jsonObject.get("username").toString());
        map.put("password", "******");
        res.setData(objectMapper.writeValueAsString(map));

        return res;
    }
}

